package com.letoken.platform.app.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.letoken.platform.app.service.AppUserWalletService;
import com.letoken.platform.app.service.WalletTokenService;
import com.letoken.platform.app.service.transfer.ITransfer;
import com.letoken.platform.pub.req.token.TokenErc20TxReq;
import com.letoken.platform.pub.res.token.TokenErc20TxRes;
import com.letoken.platform.repo.admin.manager.AdminWithdrawConfigManager;
import com.letoken.platform.repo.app.dao.TokenMapper;
import com.letoken.platform.repo.app.manager.*;
import com.letoken.platform.repo.app.req.token.WithdrawUsdtReq;
import com.letoken.platform.repo.app.res.token.LetokenTokenPriceRes;
import com.letoken.platform.repo.push.manager.AdminMQManager;
import com.letoken.platform.repo.web3.EvmProvider;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;



/**
 * @author letokenlabs
 * @date 2022/11/23$
 */
@Service
@Log4j2
public class WalletTokenServiceImpl implements WalletTokenService {

//    @Autowired
//    private AppUserAddressManager appUserAddressManager;

    @Resource
    private AdminWithdrawConfigManager withdrawConfigManager;

    @Resource
    private AppUserWalletManager walletManager;

    @Resource
    private AppUserWalletService appUserWalletService;

    @Resource
    private TokenMapper tokenMapper;

    @Autowired
    private AppUserManager appUserManager;

    @Autowired
    private AppUserAssetsHistoryManager historyManager;


    @Autowired
    private AdminMQManager adminMQManager;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private WithdrawCheckByUserIdServiceImpl userIdServiceImpl;

    @Resource
    private AppUserLockedManager appUserLockedManager;


    /**
     * 返回对应的代币价格
     *
     * @return
     */
    @Override
    public List<LetokenTokenPriceRes> querySystemTokenPrice(String netType) {
        return null;
    }


    /**
     * 提现 sudt
     *
     * @param req
     */
//    @Transactional(rollbackFor = Exception.class)
//    @Override
//    public Withdraw tokenWithdraw(WithdrawUsdtReq req) {
//        String leUserAddressOrUserId = req.getUserAddressOrUserId();
//        BigDecimal amount = req.getAmount();
//        if (amount.scale() > LetokenTokenConstant.AMOUNT_SCALE) {
//            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_020);
//        }
//
//        AppUser user = appUserManager.queryMe();
//        Integer userId = user.getId();
//
//        // 黑名单
//        if (AppWalletBlackListRedis.me().getValue(userId.toString())) {
//            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_017);
//        }
//
//        // 频率限制
//        if (AppWalletRateLimitRedis.me().isLimited(userId.toString(), "withdraw", 1)) {
//            // 加入黑名单
//            AppWalletBlackListRedis.me().setValue(userId.toString(), true);
//            // 冻结用户
//            appUserLockedManager.setUserLocked(userId, true);
//            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_017);
//        }
//
//        // 判断冻结用户
//        if(appUserLockedManager.isLocked(userId)){
//            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_017);
//        }
//
//        Integer tokenId = LetokenTokenTypeEnum.USDT.getId();
//        Token token = tokenMapper.selectById(tokenId);
//        Integer transferMode = req.getTransferMode();
//        AppUserAddress appUserAddress;
//        if (transferMode.equals(0)) {
//            //平台转账
//            if (!StringUtils.startsWithIgnoreCase(leUserAddressOrUserId, LetokenUserConstant.USER_ID_PREFIX)) {
//                //验证地址有效性
//                if (!EvmUtil.checkAddressChecksum(leUserAddressOrUserId)) {
//                    throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_015);
//                }
//            }
//            //平台内互转金额要大于0
//            if (amount.compareTo(BigDecimal.ZERO) <= 0) {
//                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_012);
//            }
//            String userAddressOrUserId = LeTokenUtil.appUserIdStartsWithLe(leUserAddressOrUserId);
//            appUserAddress = appUserAddressManager.queryWalletAddressByAddressOrId(userAddressOrUserId);
//            if (ObjectUtil.isNull(appUserAddress)) {
//                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_004);
//            }
//            // 不能给自己提现
//            if (appUserAddress.getUserId().equals(userId)) {
//                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_003);
//            }
//
//            //提现金额是否大于自己的金额 大于就报错 > 2023-03-26 add by usher
//            AppUserWallet fromAppUserWallet = walletManager.queryWalletByToken(userId, tokenId);
//            if (amount.compareTo(fromAppUserWallet.getAvailableBalance()) > 0) {
//                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_007);
//            }
//            String uuid = UUIDUtil.getUUID(16);
//            LocalDateTime now = LocalDateTime.now();
//            Withdraw withdraw = new Withdraw();
//            withdraw.setSn(uuid);
//            withdraw.setUserId(userId);
//            withdraw.setTokenId(tokenId);
//            withdraw.setChainId(token.getChainId());
//            //收款地址
//            withdraw.setAddress(leUserAddressOrUserId);
//            withdraw.setToId(appUserAddress.getUserId());
//            withdraw.setAmount(amount);
//            withdraw.setFeeAmount(BigDecimal.ZERO);
//            // 平台互转 transfer_mode 为0 反之为1
//            withdraw.setTransferMode(0);
//            withdraw.setTxid("");
//            withdraw.setStatus(TokenTransactionStatusEnum.PENDING.getValue());
//            withdraw.setIsAuto(true);
//            withdraw.setCreateTime(now);
//            withdraw.setApprovedDate(now);
//            withdraw.setResponse("");
//            //自动审核
//            withdraw.setApprovedBy(LetokenTokenConstant.SYSTEM_AUTO);
//            withdraw.setRemark("");
//            //后续添加 开始
//            withdraw.setRealAmount(withdraw.getAmount());
//            withdraw.setGasUsed(BigDecimal.ZERO);
//            // 结束
//            withdraw.setApprovedState(TokenApprovedStateEnum.ADOPT.getValue());
//            boolean insert = withdraw.insert();
//            if (insert) {
//                appUserWalletService.updateWithdrawInternalOrder(withdraw, TokenTransactionStatusEnum.COMPLETED);
//            } else {
//                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_008);
//            }
//        } else if (transferMode.equals(1)) {
//            //链上转账
//            // 先查提现配置
//            AdminWithdrawConfig withdrawConfig = withdrawConfigManager.queryByToken(tokenId);
//            if (ObjectUtil.isNull(withdrawConfig)) {
//                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_009);
//            }
//            if (amount.compareTo(BigDecimal.ONE) <= 0) {
//                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_013);
//            }
//            // 不能超过配置规定的最小数量和最大数量
//            if (amount.compareTo(new BigDecimal(withdrawConfig.getMinAmount())) < 0) {
//                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_005, "提现金额小于" + withdrawConfig.getMinAmount());
//            }
//            if (amount.compareTo(new BigDecimal(withdrawConfig.getMaxAmount())) > 0) {
//                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_006, "提现金额大于" + withdrawConfig.getMaxAmount());
//            }
//            //提现金额是否大于自己的金额 大于就报错
//            AppUserWallet fromAppUserWallet = walletManager.queryWalletByToken(userId, tokenId);
//            if (amount.compareTo(fromAppUserWallet.getAvailableBalance()) > 0) {
//                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_007);
//            }
//            appUserAddress = appUserAddressManager.queryWalletAddressByAddressOrId(leUserAddressOrUserId);
//            //链上转账不能转到平台内
//            if (ObjectUtil.isNotNull(appUserAddress)) {
//                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_015);
//            }
//            //验证地址有效性
//            if (!EvmUtil.checkAddressChecksum(leUserAddressOrUserId)) {
//                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_010);
//            }
//
//            String uuid = UUIDUtil.getUUID(16);
//            LocalDateTime now = LocalDateTime.now();
//            AppUserAssetsHistory appUserAssetsHistory = historyManager.insertHistory(userId, user.getUserName(), user.getWalletAddress(), token.getId(), token.getTokenCurrency(), uuid, amount.negate(), leUserAddressOrUserId, now);
//            //钱包校验
//            Withdraw insertWithdraw = userIdServiceImpl.withdrawCheckByUserId(userId, leUserAddressOrUserId, amount, token, uuid);
//            if (insertWithdraw != null) {
//                appUserAssetsHistory.setStatus(TokenTransactionStatusEnum.FAIL.getValue());
//                appUserAssetsHistory.insert();
//                return insertWithdraw;
//            }
//            boolean insertHistory = appUserAssetsHistory.insert();
//            if (!insertHistory) {
//                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_008);
//            }
//
//            //冻结用户的提现金额
//            int updateFlag = appUserWalletService.updateUserAmountByUserIDandCoin(amount.negate(),
//                    amount, BigDecimal.ZERO, userId, tokenId);
//            if (updateFlag <= 0) {
//                // 加入黑名单
//                AppWalletBlackListRedis.me().setValue(userId.toString(), true);
//                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_008);
//            }
//
//            Withdraw withdraw = new Withdraw();
//            withdraw.setSn(uuid);
//            withdraw.setUserId(userId);
//            withdraw.setTokenId(tokenId);
//            withdraw.setChainId(token.getChainId());
//            //收款地址
//            withdraw.setAddress(leUserAddressOrUserId);
//            //没有收款id
//            withdraw.setToId(null);
//            withdraw.setAmount(amount);
//            //手续费
//            withdraw.setFeeAmount(BigDecimal.ZERO);
//            // 平台互转 transfer_mode 为0 反之为1
//            withdraw.setTransferMode(1);
//            withdraw.setTxid("");
//            withdraw.setStatus(TokenTransactionStatusEnum.PENDING.getValue());
//            withdraw.setCreateTime(now);
//            withdraw.setApprovedDate(now);
//            withdraw.setResponse("");
//            withdraw.setRemark("");
//            withdraw.setApprovedState(TokenApprovedStateEnum.PENDING.getValue());
//            boolean flag = false;
//            //提现金额大于1000U走审核流程，否则直接通过(is_auto=1)
//            if (amount.compareTo(new BigDecimal(1000)) > 0) {
//                withdraw.setIsAuto(false);
//            } else {
//                withdraw.setIsAuto(true);
//                withdraw.setApprovedState(TokenApprovedStateEnum.ADOPT.getValue());
//                //自动审核
//                withdraw.setApprovedBy(LetokenTokenConstant.SYSTEM_AUTO);
//                flag = true;
//            }
//            boolean insert = withdraw.insert();
//            if (!insert) {
//                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_008);
//            }
//            //自动审核通过
//            WithdrawReq withdrawReq = new WithdrawReq();
//            withdrawReq.setId(withdraw.getId().toString());
//            if (flag) {
//                walletMQManager.withdraw(rabbitTemplate, withdrawReq, 1000);
//            } else {
//                //向后台推送消息
//                adminMQManager.withdrawNotify(rabbitTemplate, withdrawReq, 1000);
//            }
//        } else {
//            throw new ApiServiceException(LetokenApiResponseEnum.ERROR_WALLET_WITHDRAW_008);
//        }
//        return null;
//    }


    @Autowired
    List<ITransfer> transfers;
    @Override
    public void tokenWithdrawNew(WithdrawUsdtReq req) {
        for (ITransfer tr : transfers){
            if (null != tr.choose(req.getTransferMode())){
                tr.checkout(req).transfer(req);break;
            }
        }
    }




    @Override
    public List<TokenErc20TxRes> queryWalletTx(TokenErc20TxReq req) {
        List<TokenErc20TxRes> list;
        list = JSON.parseArray(JSON.toJSONString(EvmProvider.getInstance(req.getNetType())
                .getTokenTxs(req.getWalletAddress(), 1, 20, "desc")), TokenErc20TxRes.class);
        if (CollUtil.isEmpty(list)) {
            return null;
        } else {
            return list.stream().filter(item -> !StringUtils.equals(item.getValue(), "0")).collect(Collectors.toList());
        }
    }

    @Override
    public List<TokenErc20TxRes> queryWalletErc20Tx(TokenErc20TxReq req) {
        List<TokenErc20TxRes> tokenErc20TxList = EvmProvider.getInstance(req.getNetType())
                .getTokenErc20Txs(req.getTokenAddress(), req.getWalletAddress(), 1, 20, "desc");
        if (CollUtil.isEmpty(tokenErc20TxList)) {
            return null;
        } else {
            return tokenErc20TxList.stream().filter(item -> !StringUtils.equals(item.getValue(), "0")).collect(Collectors.toList());
        }

    }


}
